package com.institute.service;

import java.util.ArrayList;
import java.util.List;

import javax.transaction.Transactional;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;

import com.institute.dao.InstituteRepository;
import com.institute.dao.PositionRepository;
import com.institute.entity.Institute;
import com.institute.entity.Position;
import com.institute.entity.dto.PositionDTO;
import com.staff.dao.StaffRepository;
import com.staff.entity.Staff;

@Service
@Transactional
public class PositionService implements IPositionService{
	@Autowired
	private PositionRepository positionDao;
	@Autowired
	private InstituteRepository instituteDao;
	@Autowired
	private StaffRepository staffDao;
	
	public Position findOne(Long id) {
		return positionDao.findOne(id);
	}

	public List<Position> findAll() {
		return (List<Position>) positionDao.findAll();
	}


	public Institute getDept(Position position) {
		return positionDao.findOne(position.getId()).getDept();
	}

	public Integer getStaffNum(Long id) {
		return positionDao.findStaffsByPosition(id).size();
	}

	public Page<PositionDTO> findAll(Specification<Position> spec, Pageable pageable) {
		List<PositionDTO> results = new ArrayList<PositionDTO>(); 
		Page<Position> page = positionDao.findAll(spec, pageable);
		for(Position position:page.getContent()) {
			String deptName = null;
			if(positionDao.findOne(position.getId()).getDept()!=null)deptName = positionDao.findOne(position.getId()).getDept().getName();
			PositionDTO dto = new PositionDTO(position, 
					deptName, 
					positionDao.findStaffsByPosition(position.getId()).size());
			results.add(dto);
		}
		return new PageImpl<PositionDTO>(results, pageable, page.getTotalElements());
	}

	public void saveOrUpdate(PositionDTO dto) {
		if(dto.getId()!=null) {
			Position position = positionDao.findOne(dto.getId());
			position.setCode(dto.getCode());
			position.setCapacity(dto.getCapacity());
			position.setDescription(dto.getDescription());
			position.setName(dto.getName());
			positionDao.save(position);
		}else {
			Position position = new Position(dto);
			Institute father = null;
			if(dto.getFatherId() != null)father = instituteDao.findOne(dto.getFatherId());
			position.setDept(father);
			positionDao.save(position);
		}
	}

	public void delete(Long id) {
		if(hasStaffs(id))return;
		Position p = positionDao.findOne(id);
		//先移除所属部门关系，再删除
		p.setDept(null);
		positionDao.save(p);
		positionDao.delete(id);
	}

	public boolean hasStaffs(Long id) {
		if(positionDao.findStaffsByPosition(id).size()>0)return true;
		return false;
	}

	public List<PositionDTO> findByDeptName(String deptName) {
		List<Position> positions =  positionDao.findByDeptName(deptName);
		List<PositionDTO> dtos = new ArrayList<PositionDTO>();
		for(Position p:positions) {
			dtos.add(new PositionDTO(p, deptName, positionDao.findStaffsByPosition(p.getId()).size()));
		}
		return dtos;
	}

	public void changeDept(Long id, Long deptId) {
		Institute oldDept = new Institute();
		Institute dept = instituteDao.findOne(deptId);
		if(id!=null&&deptId!=null) {
			Position position = positionDao.findOne(id);
			if(position!=null&&dept!=null) {
				oldDept = position.getDept();
				position.setDept(dept);
				positionDao.save(position);
			}
			
			//更变员工部门
			List<Staff> staffs = staffDao.findByDept(oldDept.getId());
			for(Staff staff:staffs) {
				staff.setDepartment(dept);
				staffDao.save(staff);
			}
		}
	}

	public boolean isNameExist(PositionDTO dto) {
		List<Position> list = (List<Position>) positionDao.findAll();
		for(Position p:list) {
			if(dto.getId()!=p.getId()&&p.getName().equals(dto.getName()))return true;
		}
		return false;
	}

	public boolean isCodeExist(PositionDTO dto) {
		List<Position> list = (List<Position>) positionDao.findAll();
		for(Position p:list) {
			if(dto.getId()!=p.getId()&&p.getCode().equals(dto.getCode()))return true;
		}
		return false;
	}

}
